/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gui;

/**
 *
 * @author root
 */
import java.io.*;

public class doRLE_compress {
   
   
      final static boolean DisplaySize  = true;
      final static boolean DisplayFilenames  = true;
     
      FileOutputStream OutputStream = null;
      FileInputStream InputStream = null;
      byte[] CharHolder = new byte[1];
   
  
      public void doCompression(String InputFile, String OutputFile) throws IOException {
         long start_time;
      
         if (DisplayFilenames) {
            printf("Original file:   " + InputFile);
            printf("Compressed file: " + OutputFile);
         }
      
               
    
         try {
            InputStream = new FileInputStream(InputFile);
            OutputStream = new FileOutputStream(OutputFile);      
            int ReadByte;
         
            int LastCharacter = -1;
            int SecondLastCharacter = -2;
            int TempChar;
            while ((TempChar = getNextCharacter()) != -1) {
               putCharacterInOutputStream(TempChar);  
               
               if (SecondLastCharacter == LastCharacter) {
                  if (TempChar == LastCharacter) {
                     int RepeatCount = 0;
                         while (( TempChar = getNextCharacter()) >= 0 ) {
                            if (TempChar == LastCharacter) {
                               RepeatCount++;
                            }
                            else
                            {
                               break;
                            }
                         }
                  
                         if ( TempChar < 0 ) {
                            if ((RepeatCount >= 256) && (RepeatCount % 256 == 0)) {
                               RepeatCount -=256; 
                               
                            }
                            else {
                               if ( RepeatCount == 0 ) RepeatCount = -1;
                            }
                         }
                         if (RepeatCount >=0) {
                             
                            putCharacterInOutputStream(RepeatCount);
                         }

                         while ((RepeatCount = RepeatCount - 256) >= 0) {
                              
                            putCharacterInOutputStream(LastCharacter);
                         }

                         if (TempChar >= 0) {
                             
                            putCharacterInOutputStream(TempChar);
                         }
                  }
               }
               
               SecondLastCharacter = LastCharacter;
               LastCharacter = TempChar;
            }
         
            InputStream.close();
            OutputStream.close();
         }
            catch(Exception e) {
               printf("An unknown error has occured while dealing with the file:");
               e.getMessage();
            }
      
         
      
         if (DisplaySize) {
            File inFile = new File(InputFile);
            File outFile = new File(OutputFile);
         
            long inFileLength = inFile.length();
            long outFileLength = outFile.length();
         
            printf("Original file size:   " + inFileLength + " bytes.");
         
            printf("Compressed file size: " + outFileLength + " bytes.");
            if (inFileLength > outFileLength) {
               printf("Compressed by " + (inFileLength - outFileLength) + " bytes.");
            }
            else
            {
               printf("*** File gained in size by " + (outFileLength - inFileLength) + " bytes. ***");
            }
         
     
            if (inFileLength == 0L) {
               inFileLength = 1L;
            }
         
            printf("Compression ratio:    " + ((((inFileLength - outFileLength) * 10000) / inFileLength) / 100F) + "%");
         
         }
      
         printf("");
      }
   
   
      int getNextCharacter() throws IOException {
         int ReadByte;
      
         if ((ReadByte = InputStream.read(CharHolder, 0, 1)) == -1) {
            return -1;
         }
      
         return CharHolder[0] ;
      }
   
   
      void putCharacterInOutputStream(int i) throws IOException {
         OutputStream.write((byte)i);
      }
   
   
      static void printf(String s) {              
         System.out.println(s);
      }
   
  
      public static void main(String[] args) throws IOException {
         doRLE_compress RLE = new doRLE_compress();
      
         String InputFile = null;
         String OutputFile = "n1";
      
         printf("RLE Algorithm:\n ");
      
         if (args.length > 0) {
            InputFile = args[0];
         } 
         else {
            printf("Error: No input file specified");
            System.exit(0);
         }
      
         if (args.length > 1) {
            OutputFile = args[1];
         } 
         else {
            printf("Error: No output file specified");
            System.exit(0);
         }
      
         RLE.doCompression(InputFile, OutputFile);
      }
   
   }


